//
// Created by daybeha on 2022/7/12.
//

#include "loopclose.h"



bool loopclose::loadPython(){
//    Py_Initialize(); //初始化Python环境
//    if (!Py_IsInitialized()) //检测是否初始化成功
//    {
//        return false;
//    } else {
//        PyEval_InitThreads();     //开启多线程支持
//        int nInit = PyEval_ThreadsInitialized();  //检测线程支持是否开启成功
//        if (nInit) {
//            PyEval_SaveThread();  //因为调用PyEval_InitThreads成功后，当前线程就拥有了GIL，释放当前线程的GIL，
//        }
//    }

//    PyGILState_STATE gstate;
//    gstate = PyGILState_Ensure();   //如果没有GIL，则申请获取GIL
//    Py_BEGIN_ALLOW_THREADS;
//        Py_BLOCK_THREADS;



//        Py_UNBLOCK_THREADS;
//    Py_END_ALLOW_THREADS;
//    PyGILState_Release(gstate);    //释放当前线程的GIL

    return true;
}
/**
 * @brief 图像拼接
 * @param[in] images    原始图像
 * @param[in] type      0：横向拼接； 1： 纵向拼接
 * */
cv::Mat ImageSplicing(vector<cv::Mat> images, int type) {
    if (type != 0 && type != 1)
        type = 0;

    int num = images.size();
    int newrow = 0;
    int newcol = 0;
    cv::Mat result;

    // 横向拼接
    if (type == 0) {
        int minrow = 10000;
        for (int i = 0; i < num; ++i) {
            if (minrow > images[i].rows)
                minrow = images[i].rows;
        }
        newrow = minrow;
        for (int i = 0; i < num; ++i) {
            int tcol = images[i].cols * minrow / images[i].rows;
            int trow = newrow;
            cv::resize(images[i], images[i], cv::Size(tcol, trow));
            newcol += images[i].cols;
            if (images[i].type() != images[0].type())
                images[i].convertTo(images[i], images[0].type());
        }
        result = cv::Mat(newrow, newcol, images[0].type(), cv::Scalar(255, 255, 255));

        cv::Range rangerow, rangecol;
        int start = 0;
        for (int i = 0; i < num; ++i) {
            rangerow = cv::Range((newrow - images[i].rows) / 2, (newrow - images[i].rows) / 2 + images[i].rows);
            rangecol = cv::Range(start, start + images[i].cols);
            images[i].copyTo(result(rangerow, rangecol));
            start += images[i].cols;
        }
    }
        // 纵向拼接
    else if (type == 1) {
        int mincol = 10000;
        for (int i = 0; i < num; ++i) {
            if (mincol > images[i].cols)
                mincol = images[i].cols;
        }
        newcol = mincol;
        for (int i = 0; i < num; ++i) {
            int trow = images[i].rows * mincol / images[i].cols;
            int tcol = newcol;
            cv::resize(images[i], images[i], cv::Size(tcol, trow));
            newrow += images[i].rows;
            if (images[i].type() != images[0].type())
                images[i].convertTo(images[i], images[0].type());
        }
        result = cv::Mat(newrow, newcol, images[0].type(), cv::Scalar(255, 255, 255));

        cv::Range rangerow, rangecol;
        int start = 0;
        for (int i = 0; i < num; ++i) {
            rangecol = cv::Range((newcol - images[i].cols) / 2, (newcol - images[i].cols) / 2 + images[i].cols);
            rangerow = cv::Range(start, start + images[i].rows);
            images[i].copyTo(result(rangerow, rangecol));
            start += images[i].rows;
        }
    }

    return result;
}

void loopclose::run(){
//    Py_Initialize(); //初始化Python环境
//    if (!Py_IsInitialized()) //检测是否初始化成功
//    {
//        return;
//    } else {
//        PyEval_InitThreads();     //开启多线程支持
//        int nInit = PyEval_ThreadsInitialized();  //检测线程支持是否开启成功
//        if (nInit) {
//            PyEval_SaveThread();  //因为调用PyEval_InitThreads成功后，当前线程就拥有了GIL，释放当前线程的GIL，
//        }
//    }


    PyGILState_STATE gstate;
    gstate = PyGILState_Ensure();   //如果没有GIL，则申请获取GIL
    Py_BEGIN_ALLOW_THREADS;
        Py_BLOCK_THREADS;

        PyRun_SimpleString("import sys\n");
        PyObject *sys_path = PySys_GetObject("path");
        PyList_Append(sys_path,
                      PyUnicode_FromString("/home/daybeha/Documents/github/DeepLabV3_ws/src/superglue/script"));
        PyRun_SimpleString("print(sys.path)");

        // 检查当前Python版本
        PyRun_SimpleString("import platform\n"
                           "print(f\"\\033[92m Python Version: {platform.python_version()}\\033[0m\")\n");

        // 在C中使用numpy之前一定要先 import_array()
        // https://numpy.org/doc/1.13/reference/c-api.array.html#c.import_array
        // this macro is defined be NumPy and must be included
//        import_array1(-1);
        _import_array();

        // 导入 python 模块
        pModule = PyImport_ImportModule(python_modle);

        if (pModule != NULL) {
            cout << "loaded " << python_modle << endl;

            // 获取目标python函数
            pFunc = PyObject_GetAttrString(pModule, python_func);

            /* pFunc is a new reference */
            if (pFunc && PyCallable_Check(pFunc)) {

            } else {
                if (PyErr_Occurred())
                    PyErr_Print();
                fprintf(stderr, "Cannot find function \"%s\"\n", python_func);
            }
            Py_XDECREF(pFunc);
            Py_DECREF(pModule);
        } else {
            PyErr_Print();
            fprintf(stderr, "Failed to load \"%s\"\n", python_modle);
            return;
        }


//    for (int i = 1; i < 5; ++i) {

        stringstream ss0, ss1;
//        ss0 << setfill('0') << setw(6) << i;
        ss0 << setfill('0') << setw(6) << 0;


        // 读取图片
        cv::Mat img0 = cv::imread("/home/daybeha/Documents/Dataset/Kitti/sequences/00/image_0/"+  ss0.str() +".png",
                                  cv::IMREAD_GRAYSCALE);
//        ss1 << setfill('0') << setw(6) << i+20;
        ss1 << setfill('0') << setw(6) << 20;
        cv::Mat img1 = cv::imread("/home/daybeha/Documents/Dataset/Kitti/sequences/00/image_0/"+  ss1.str() +".png",
                                  cv::IMREAD_GRAYSCALE);
        cout << ss0.str()<<endl;
        cout << ss1.str()<<endl;

        vector<cv::Mat> imgs;
        imgs.emplace_back(img0);
        imgs.emplace_back(img1);
        Mat ret = ImageSplicing(imgs, 1);
        cv::imshow("ret", ret);
        cv::waitKey();

//        pFunc = PyObject_GetAttrString(pModule, python_func);

        float score = compute_match_score(img0, img1);
        cout << "b, score: " << score << endl;


//    }
        Py_UNBLOCK_THREADS;
    Py_END_ALLOW_THREADS;
    PyGILState_Release(gstate);    //释放当前线程的GIL

}
